﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using XXF.BaseService.ConfigManager.SystemRuntime;
using XXF.ProjectTool;

namespace XXF.BaseService.ConfigManager
{
    /// <summary>
    /// 配置中心使用帮助类
    /// </summary>
    public class ConfigManagerHelper
    {
        private static object _singletonlock = new object();
        private static ConfigManagerHelper _singletonobject;
        private static DeadLoopCheck _deadloopcheck = new DeadLoopCheck();
        private static string errorinfo = "当前项目的配置项{0}未配置配置信息,请使用配置中心或者app.config/web.config进行该配置项配置。若使用配置中心,";

        private ConfigManagerHelper()
        {
        }

        static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            try
            {
                if (_singletonobject != null)
                {
                    ConfigHeartbeatProtect.Instance().Dispose();
                    LogHelper.Log(-1, string.Format("当前域进程退出时释放完毕,服务器ip地址:{0}", CommonHelper.GetDefaultIP()));
                }
            }
            catch (Exception exp)
            {
                LogHelper.Error(-1,  string.Format("当前域进程退出时释放出错,服务器ip地址:{0}", CommonHelper.GetDefaultIP()), exp);
                throw exp;
            }
        }
        static void CurrentDomain_DomainUnload(object sender, EventArgs e)
        {
            try
            {
                if (_singletonobject != null)
                {
                    ConfigHeartbeatProtect.Instance().Dispose();
                    LogHelper.Log(-1, string.Format("当前域域卸载时释放完毕,服务器ip地址:{0}", CommonHelper.GetDefaultIP()));
                }
            }
            catch (Exception exp)
            {
                LogHelper.Error(-1,  string.Format("当前域域卸载释放出错,服务器ip地址:{0}", CommonHelper.GetDefaultIP()), exp);
                throw exp;
            }
        }
        /// <summary>
        /// 获取当前配置中心唯一实例
        /// </summary>
        /// <returns></returns>
        public static ConfigManagerHelper GetInstance(string configkey)
        {
            if (_singletonobject == null)
            {
                lock (_singletonlock)
                {
                    if (_singletonobject == null)
                    {
                        if (XXF.Common.XXFConfig.ProjectName == "未命名项目" || string.IsNullOrWhiteSpace(XXF.Common.XXFConfig.ProjectName))
                        {
                            throw new Exception(string.Format(errorinfo, configkey) + "请选择请在web.config或AppSettings.config中配置ProjectName,或在代码中设置XXF.Common.XXFConfig.ProjectName");
                        }
                        if (string.IsNullOrWhiteSpace(XXF.Common.XXFConfig.ConfigManagerConnectString))
                            throw new ConfigException(string.Format(errorinfo, configkey) + "请在web.config或AppSettings.config中配置ConfigManagerConnectString");

                        string redisserver = "";
                        try
                        {
                            SqlHelper.ExcuteSql(XXF.Common.XXFConfig.ConfigManagerConnectString, false, (c) =>
                            {
                                redisserver = SystemConfigHelper.GetRedisServer(c);
                            });
                        }
                        catch (Exception exp)
                        {
                            _deadloopcheck.AddError("");
                            LogHelper.Error(-1, "初始化系统配置加载出错", exp);
                        }

                        AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;
                        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
                        ConfigContext context = new ConfigContext(); context.ConfigParams = new ConfigParams() { ProjectName = XXF.Common.XXFConfig.ProjectName, ConfigManagerConnectString = XXF.Common.XXFConfig.ConfigManagerConnectString, RedisServer = redisserver };
                        AppDomainContext.Context = context;
                        ConfigHeartbeatProtect.Instance().LoadConfig(false);
                        _singletonobject = new ConfigManagerHelper();
                        LogHelper.Debug("ConfigManagerHelper单例实例创建成功");
                    }
                }
            }
            return _singletonobject;
        }

        /// <summary>
        /// 获取配置
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configkey">配置的key（配置项）</param>
        /// <returns></returns>
        public static T Get<T>(string configkey)
        {
            try
            {
                string value = null;
                if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains(configkey))
                {
                    value = System.Configuration.ConfigurationManager.AppSettings[configkey];
                }
                else
                {
                    if (GetInstance(configkey) != null)
                    {
                        if (AppDomainContext.Context == null || AppDomainContext.Context.ConfigInfoOfKeyDic == null)
                            throw new ConfigException("当前项目未在配置中心获取配置列表");
                        var config = AppDomainContext.Context.ConfigInfoOfKeyDic.GetConfig(configkey);
                        if (config == null)
                            throw new ConfigException(string.Format("未找到当前配置项,请联系管理员在配置中心中添加.key:{0}", configkey));
                        value = config.Value();

                        _deadloopcheck.ReSet();
                    }
                }
                return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
            }
            catch (Exception exp)
            {
                _deadloopcheck.AddError(configkey);
                LogHelper.Error(-1, "统一配置中心获取配置失败", exp);
                throw exp;
            }
        }

        /// <summary>
        /// 判断配置是否存在配置
        /// </summary>
        /// <param name="configkey">配置的key（配置项）</param>
        /// <returns></returns>
        public static bool TryGet(string configkey)
        {
            try
            {
                bool existFlag = true;
                if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains(configkey))
                {
                    existFlag = true;
                }
                else
                {
                    if (GetInstance(configkey) != null)
                    {
                        if (AppDomainContext.Context == null || AppDomainContext.Context.ConfigInfoOfKeyDic == null)
                            throw new ConfigException("当前项目未在配置中心获取配置列表");
                        var config = AppDomainContext.Context.ConfigInfoOfKeyDic.GetConfig(configkey);
                        if (config == null)
                        {
                            existFlag = false;
                        }
                        else
                        {
                            existFlag = true;
                        }
                        _deadloopcheck.ReSet();
                    }
                }
                return existFlag;
            }
            catch (Exception exp)
            {
                _deadloopcheck.AddError(configkey);
                LogHelper.Error(-1, "统一配置中心获取配置失败", exp);
                throw exp;
            }
        }


    }
}
